from django.conf import settings
from django.shortcuts import render
import os
from alipay import AliPay
from django.http import JsonResponse
from django.views import View

from apps.orders.models import OrderInfo
from apps.payment.models import Payment
from meiduo_mall.utils.views import LoginRequiredJSONMixin


# Create your views here.


class PaymentView(LoginRequiredJSONMixin, View):
    """支付宝支付
    GET /payment/(?P<order_id>\d+)/
    """

    def get(self, request, order_id):
        """
        对接支付宝的支付接口
        :param order_id: 要支付的订单号
        :return: 支付宝收银台扫码登录链接
        """
        # 校验order_id是否存在
        try:
            # 要去支付的订单必须订单编号存在，而且必须是当前登录用户本人的订单，而且订单的状态必须是待支付
            user = request.user
            order = OrderInfo.objects.get(order_id=order_id,
                                          user=user,
                                          status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        # except OrderInfo.DoesNotExist:
        #     return JsonResponse({'code': 400, 'errmsg': '参数order_id错误'})
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': 'order_id有误'})

        """
               如果是安装的最新的支付宝SDK，读取秘钥的方式是读取秘钥字符串
               app_private_key_string = open("/path/to/your/private/key.pem").read()
               alipay_public_key_string = open("/path/to/alipay/public/key.pem").read()

               app_private_key_string=app_private_key_string,
               alipay_public_key_string=alipay_public_key_string,
               """
        # 对接支付宝的支付接口
        # 创建AliPay的SDK对象
        alipay = AliPay(
            # 应用的ID，如果对接的是沙箱应用，那么就是沙箱应用的ID。反之，就是正式应用的ID
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            # 私钥文件地址
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                              "keys/app_private_key.pem"),
            # 公钥文件地址
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                "keys/alipay_public_key.pem"),
            sign_type="RSA2",
            debug=settings.ALIPAY_DEBUG
        )

        # 生成登录支付宝连接
        # 使用AliPay的SDK对象调用支付的接口函数接口，得到收银台扫码登录路径order_string
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 美多商城维护的订单号
            total_amount=str(order.total_amount),  # 实付款
            subject="美多商城%s" % order_id,
            return_url=settings.ALIPAY_RETURN_URL,  # 支付成功后的回调地址
        )

        # 响应登录支付宝连接
        # 真实环境电脑网站支付网关：https://openapi.alipay.com/gateway.do? + order_string
        # 沙箱环境电脑网站支付网关：https://openapi.alipaydev.com/gateway.do? + order_string
        alipay_url = settings.ALIPAY_URL + "?" + order_string

        # 响应结果
        return JsonResponse({'code': 0,
                             'errmsg': 'OK',
                             'alipay_url': alipay_url})


class PaymentStatusView(LoginRequiredJSONMixin, View):
    """处理支付成功的回调
    PUT /payment/status/
    """

    def put(self, request):
        """保存支付结果"""
        # 接受参数：支付宝回调地址中的查询字符串参数
        query_dict = request.GET

        # 使用参数验证该回调是否是支付宝的回调
        # 将查询字符串参数转字典
        data_dict = query_dict.dict()
        # 再从参数字典中剔除并获取sign参数
        signature = data_dict.pop("sign")

        # 创建AliPay的SDK对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,  # 应用的ID，如果对接的是沙箱应用，那么就是沙箱应用的ID。反之，就是正式应用的ID
            app_notify_url=None,  # 默认回调url
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"),
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                "keys/alipay_public_key.pem"),
            sign_type="RSA2",
            debug=settings.ALIPAY_DEBUG
        )

        # 校验这个重定向是否是alipay重定向过来的
        success = alipay.verify(data_dict, signature)
        if success:
            # 说明该回调是支付宝发送的安全回调
            # 读取支付宝和美多商城维护的订单号，并且绑定到一起
            out_trade_no = data_dict.get('out_trade_no')  # 美多订单号
            trade_no = data_dict.get('trade_no')  # 支付宝订单号
            Payment.objects.create(
                order_id=out_trade_no,
                trade_id=trade_no
            )

            # 修改订单状态为待评价
            # order = OrderInfo.objects.get(order_id=out_trade_no, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
            # order.status = OrderInfo.ORDER_STATUS_ENUM['UNCOMMENT']
            # order.save()
            OrderInfo.objects.filter(order_id=out_trade_no,
                                     status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']).update(
                status=OrderInfo.ORDER_STATUS_ENUM["UNCOMMENT"])

            # 响应结果
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'trade_id': trade_no})
        else:
            # 订单支付失败，重定向到我的订单
            return JsonResponse({'code': 400,
                                 'errmsg': '非法请求'})
